//
//  undergroundController.m
//  ElektroM
//
//  Created by Michael on 09.10.09.
//  Copyright 2009 Artgruppe inc. All rights reserved.
//

#import "undergroundController.h"
#import "graphCalc.h"
#import "mainViewController.h"
#import "showInfoWindow.h"
#import "uStationSelector.h"
#import "Constants.h"
#import "helpForUnderground.h"
#import "dataBase.h"
#import "drawingCanvas.h"
#include "MyMath.h"


@implementation undergroundController

@synthesize infoWindow;
@synthesize databaseName;
@synthesize helpController;
@synthesize image;
@synthesize scrollView;
@synthesize selectStations;
@synthesize upperToolbar;
@synthesize station1, station2;
@synthesize mainController;
@synthesize timeOfJourney;


 // The designated initializer.  Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
		
	}
	
    return self;
}


- (void)viewDidLoad {
  [super viewDidLoad];
	
	CGRect old=scrollView.frame;
	scrollView.frame=CGRectMake(old.origin.x, old.origin.y, 
								old.size.width+7, old.size.height+7);
	
	[scrollView setBackgroundColor:[UIColor whiteColor]];
	[scrollView setCanCancelContentTouches:NO];
	scrollView.clipsToBounds = YES;	// default is NO, we want to restrict drawing within our scrollview
	scrollView.indicatorStyle = UIScrollViewIndicatorStyleDefault /* UIScrollViewIndicatorStyleBlack*/;
	//image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"metroMoscow.jpg"]];
	NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
	//printf("Fog setting: %s\n", [[defaults objectForKey: kFogSetting] UTF8String]);
	if([[defaults objectForKey: kFogSetting] isEqualToString:@"showFog"] || [defaults objectForKey: kFogSetting] ==nil){
		//printf("Fog must be shown!\n");
		_bShowFog=true;				
	}
	upperToolbar.alpha = (double)([[defaults objectForKey: kAlphaUPanelUp] intValue])/100.0f;
	if(upperToolbar.alpha < 0.1f)
		upperToolbar.alpha=1.0f;
	NSString* sUBahnImage= [defaults objectForKey:kImageType];	
	if([sUBahnImage isEqualToString: @"locale"])
		_bLoadImageByLocale=true;
	else
		_bLoadImageByLocale=false;
	if(!_bLoadImageByLocale)
	{
		if([sUBahnImage isEqualToString: @"ru"])
			_nImage=1;
		else
			_nImage=0;
	}
	
	[tapWarning setText: NSLocalizedString(@"TapTwiceLabel", @"")];	
	[self setTitle:NSLocalizedString(@"undergroundTitle", @"")]; 
	[self loadAllNeededStuff];
	//printf("I'm at the end of viewDidLoad!\n");	
}

-(void) loadAllNeededStuff
{	
    //printf("I'll load all needed rerources!\n");
    if(self.image==nil)
    {
	if(_bLoadImageByLocale){
	    NSLocale *locale = [NSLocale currentLocale];
	    if([[locale localeIdentifier] isEqualToString: @"ru_RU"])
	       image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"metroImageRus.png"]];
	    else
		image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"metroImageEng.png"]];
	}
	else
	{
	    if(_nImage==1)
		image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"metroImageRus.png"]];
	    else
		image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"metroImageEng.png"]];

	}
	[scrollView addSubview:image];	
	[scrollView setContentSize:CGSizeMake(image.frame.size.width, image.frame.size.height)];
	[scrollView setScrollEnabled:YES];
	////self.scrollView.userInteractionEnabled = YES;		
    }
    // set-up the scroll view:    
    scrollView.type=1;   

    _nFirstFoundStation=-1;	
    _nSecondFoundStation=-1;	
    // update canvas (drawing stuff):
    canvas.scroll=scrollView;
    [canvas initization];

    // load resources needed for showing and calculating connections between stations:
    if(_db!=nil)
    {
	[_db release];
	_db = nil;
    }
    _db=[dataBase alloc];
    // I cannot use the DB for that purposes, do not why.. and do not want to solve 
    // the problem at so late hour
    _db.databaseName=kDBUnderground;
    [_db initialization];	
   
    // get centers' info from the DB:
    _aiCenterX = [_db readCentersAsNSArrayLoadRailways: false];
    _aiCenterY = [_db getUCentersYAsNSArray];

    _aiDrawInfo = [_db readUStationsDrawInfoAsNSArray];

    _aiUStationNames=[_db readUStationsAsNSArray];		
    _aiULineNames=[_db getULineNamesAsNSArray];	
    _aiiULineNumbers=[_db getULineNumbersAsNSArray];
    _aiiUStationIds = [_db getUStationIdsAsNSArray];

    _aiNodes = [_db readUStationToStationStructure];
    _aiLineNumbers = [_db getCycloneLineNumbers];
    _graph = [graphCalc alloc];
    // initalize it:
    [_graph setLineNumbers: _aiLineNumbers];
    [_graph setNodes: _aiNodes];
    [_graph init];
    // do that stuff for not deleting allocated memory (wrong policy):
    //[_aiNodes retain];
    //[_aiLineNumbers retain];

    _nFirstFoundStation=[master storageGetSelectedStations:3 FromController:@""];
    _nSecondFoundStation=[master storageGetSelectedStations:4 FromController:@""];
    //printf("id1: %d, id2: %d\n", _nFirstFoundStation, _nSecondFoundStation);
    if(_nFirstFoundStation>=[_aiNodes count] || _nFirstFoundStation<0)
	_nFirstFoundStation=-1;
    if(_nSecondFoundStation>=[_aiNodes count] || _nSecondFoundStation<0)
	_nSecondFoundStation=-1;	
		
	if(_nFirstFoundStation!=-1 && _nSecondFoundStation!=-1)
	_nCountOfAllowedLines=[_db getUStationsCountOfAllowedLinesWithStart: 
						   [[_aiLineNumbers objectAtIndex: _nFirstFoundStation] intValue]
							 andEnd:[[_aiLineNumbers objectAtIndex: _nSecondFoundStation] intValue]  ];
	_nCurSelectedPath=-1;

    if(_nFirstFoundStation!=-1)
	[self recalculateGraph];
    [self updateInterface];
	
	[busy stopAnimating];
}

-(void) releaseAllStuff
{
	//printf("I'll remove all rerources! (Underground)\n");
    if(_graph!=nil){		
		[_graph cleanUp];
		[_graph release];
		_graph=nil;
	}
	
    [_db cleanCentersInfo];
    [_db releaseUStationAsNSArrayResources];
    if(_aiDrawInfo!=nil)
	[_aiDrawInfo release];
    _aiDrawInfo=nil;
   
    [canvas utilization];
    [self.image removeFromSuperview];
    self.image=nil;
	
	if(_db!=nil)
	{
		_db.databaseName=nil;
		[_db releaseUStation2StationResources];
		[_db release];
		_db=nil;
	}
	
}

#pragma mark -
#pragma mark Interface
-(void) disableUserIteraction
{
    self.navigationController.navigationBar.userInteractionEnabled = NO;
    scrollView.userInteractionEnabled = NO;
    upperToolbar.userInteractionEnabled = NO;
}

-(void) enableUserIteraction
{
    self.navigationController.navigationBar.userInteractionEnabled = YES;
    scrollView.userInteractionEnabled = YES;
    upperToolbar.userInteractionEnabled = YES;
}

-(void) updateInterface
{	
	_bReformDrawBuffer=true;
    // delete old points:    
	[canvas haveToDestroyBuffer];
    // and form the new ones:
    [self drawSelection];
    [canvas DrawThemAll];
    //[canvas setNeedsDisplayInRect: [canvas getRectToUpdate]];
    _bReformDrawBuffer=false;

    //printf("Updating Interface... _nFirstFoundStation: %d; _nSecondFoundStation:%d\n", _nFirstFoundStation, _nSecondFoundStation);
    if(_nFirstFoundStation!=-1)
    {
	station1.text=[_aiUStationNames objectAtIndex: _nFirstFoundStation];
    }
    else{
	station1.text=@"X";
    }

    if(_nSecondFoundStation!=-1)
    {
	station2.text=[_aiUStationNames objectAtIndex: _nSecondFoundStation];
	timeOfJourney.text=[NSString stringWithFormat:@"%d %@", [_graph getWeight: _nSecondFoundStation],
	    NSLocalizedString(@"min", @"")];
	if(!_bBigUpBar && !_bBigToolbarWasShownBefore)
	{
	    [self changeBigSmallUpBar];
	}
    }
    else{
	station2.text=@"X";
	timeOfJourney.text=NSLocalizedString(@"SelStation", @"");
    }		

    [upperToolbar setNeedsDisplay];
    //[self showInfoOnAnyOfStations];
    [self enableUserIteraction];
}

#pragma mark -
#pragma mark Touches
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {	
	//printf("Touch!\n");
    UITouch *touch = [[event allTouches] anyObject];
    CGPoint ptWhere = [touch locationInView:touch.view];

    if([touch tapCount]>=2 && !upperToolbar.hidden){
	[self hideToolbarWithAnimationAndInfo:1];	
	_bUpperToolbarShown=false;
    }
    else if([touch tapCount]>=2 && upperToolbar.hidden){
	[self showToolbarWithAnimationAndInfo:0];	
	_bUpperToolbarShown=true;
    }

    // system hangs on, if you tap here two times! 
    // construction like that doesn't really help:
					 // FIXED: used timer;

					 //printf("Count: %d\n", [touch tapCount]);
    _bAreWeInScrollMode=false;
    if([touch tapCount]==1){
	_bNeedToCalculateGraph=true;
	[NSTimer scheduledTimerWithTimeInterval: 0.1f
					 target:self selector:@selector(performGraphCalc) 
				       userInfo:nil repeats: NO];	
	//printf("Point to find from %.0f; %.0f\n", ptWhere.x, ptWhere.y);
	//[self findStationInPoint:ptWhere];	
	_ptWhereLast=ptWhere;
    }
    else
	_bNeedToCalculateGraph=false;
}

-(void) performGraphCalc
{
    if(_bNeedToCalculateGraph)
	[self findStationInPoint: _ptWhereLast];
}
// update our view as we do the scroll process:
- (void)scrollViewDidScroll:(UIScrollView *)scrollViewChanged
{	
    _bAreWeInScrollMode=true;	 
}
#pragma mark -
#pragma mark C++ Stuff
-(void)findStationInPoint:(CGPoint) ptCur
{
    [self disableUserIteraction];
	// an array to sort out found stations with minimum distance to 
	// our point:
	int* found_mins;
	int nFoundCount=0;
	int getN=10;
	for(int i=0; i<[_aiCenterX count]; i++)
	{		
	    // here we should translate our coordinates into 
	    // the coordinate system of the image...
	    // that's why we have to add ptMetroLeftCorner
	    double dDist=sqrt(sqr([[_aiCenterX objectAtIndex: i] intValue]-ptCur.x
							  +image.frame.origin.x)+
						  sqr([[_aiCenterY objectAtIndex: i] intValue] -ptCur.y+
							  image.frame.origin.y));
	    if(fabs(dDist) < kMinDistanceToPoint)
	    {
			// memory allocation:
			if(nFoundCount==0)
				found_mins=(int*)malloc(sizeof(int)*getN);
			if(nFoundCount>getN)
			{
				getN*=2;
				int *anTmp=(int*)malloc(sizeof(int)*getN);
				for(int j=0; j<nFoundCount; j++)
					anTmp[j]=found_mins[j];
				
				free(found_mins);
				found_mins=anTmp;
			}
			// add found node to the array:
			found_mins[nFoundCount++]=i;
	    }
	}
	int min=Infinity;
	int j=0;
	int min_ind=-1;
	for(int i=0; i<nFoundCount; i++)
	{	    
	    j=found_mins[i];
	    double dDist=sqrt(sqr([[_aiCenterX objectAtIndex: j] intValue]-ptCur.x)+
						  sqr([[_aiCenterY objectAtIndex: j] intValue]-ptCur.y));
		if( dDist < min)
	    {
			min=dDist;
			min_ind=j;
	    }
	}	
	free(found_mins);
	//printf("I'm before min_ind! %d\n", min_ind);
	// now show the found station:
	if(min_ind!=-1){
	    // for testing purposes show the station:
	    if(_nFirstFoundStation==-1 /*|| abs(_nFirstFoundStation-min_ind)<3*/)
		_nFirstFoundStation=min_ind;
	    else /*if(abs(_nFirstFoundStation-min_ind)>3 || abs(_nSecondFoundStation-min_ind)<3)*/{
			// need to find out what line numbers we can use;
			/*
			 if(_nSecondFoundStation!=min_ind)				
			{
				
				if(_db==nil)
				{
					_db=[dataBase alloc];
					_db.databaseName=kDBUnderground;
				}
				[_db initialization];	
				_nCountOfAllowedLines=[_db getUStationsCountOfAllowedLinesWithStart: 
									   [[_aiLineNumbers objectAtIndex: _nFirstFoundStation] intValue]
										 andEnd:[[_aiLineNumbers objectAtIndex: _nSecondFoundStation] intValue]  ];
				_nCurSelectedPath=-1;
				 
			}				
			*/
			_nSecondFoundStation=min_ind;
			
	    }
	    //NSLog(@"1: %d; 2: %d;", _nFirstFoundStation, _nSecondFoundStation);
	    if(_nFirstFoundStation==min_ind){			
		// recalculate the nodes:
			[self recalculateGraph];
	    }

		_nLastNumber=min_ind;
		[self updateInterface];
	}
	else
	    [self enableUserIteraction];
	//printf("I'm afer min_ind!\n");
}

-(void) showInfoOnAnyOfStations
{
    // now try to find, if there are some 
    // records in the sightseeing db:
   if([_aiSStationIds containsObject:[NSNumber numberWithInt: _nSecondFoundStation]] || 
	  [_aiSStationIds containsObject:[NSNumber numberWithInt: _nFirstFoundStation]])      
  	{
	    if(_bSightsWereShown && !_bHideInfoPanelWasForced
		    && [_aiSStationIds containsObject: [NSNumber numberWithInt: _nLastNumber]])
	    {
		//printf("User wants hide the panel!\n");
		_bHideInfoPanelWasForced=true;
		// user wants to hide that awful panel, oblidge him:
		if(!showSightseeings.hidden)
		    [self hideToolbarInfoWithAnimationAndInfo:0];
		else
		    [self showToolbarInfoWithAnimationAndInfo:0];

		return;
	    }
	    else if(_bHideInfoPanelWasForced && _bSightsWereShown
		    && ([_aiSStationIds containsObject:[NSNumber numberWithInt: _nLastNumber]]))
		return;

	    _bSightsWereShown=true;
	    //printf("Panel wake up!\n");
	    //showSightseeings.tag=number;
	    if(showSightseeings.hidden)
		[self showToolbarInfoWithAnimationAndInfo:0];		
	    return;
	}	
	// there are no stations with any data attached to them,
	// hide the panel and tell the system to show the info panel 
	// next time:
	//printf("We haven't found the elements, panel go back!\n");
	_bSightsWereShown=false;
	_bHideInfoPanelWasForced=false;
	
	[self hideToolbarInfoWithAnimationAndInfo:0];	
}

-(void) recalculateGraph
{
    //printf("Recalculating Graph...\n");
    [_graph setStart: _nFirstFoundStation];
    [_graph applyCyclon];
	_nCurSelectedPath=0;
    /*
    [_graph printWeights];
     */
}

-(IBAction) showNextStation
{
	if(_nCurSelectedPath>=(NSInteger)_nCountOfAllowedLines)
		return;
	
	_nCurSelectedPath++;
	//int nTime=[_graph getWeight: _nSecondFoundStation];
	[_db initialization];
	
	int* nAllowed=[_db getUStationsAllowedLinesWithStart:  
				   [[_aiLineNumbers objectAtIndex: _nFirstFoundStation] intValue]
								  andEnd:[[_aiLineNumbers objectAtIndex: _nSecondFoundStation] intValue]
									andIndex: _nCurSelectedPath];
	int nCount=[_db getUStationsCountOfAllowedLinesArray];
	[_graph applyCyclonC: nAllowed withAllowedCount: nCount];
	[self updateInterface];
	[_aiLineNumbers retain];
	free(nAllowed);
}

-(IBAction) showPrevStation
{
	if(_nCurSelectedPath==-1)
		return;
	// show the fastest way:
	if(_nCurSelectedPath==0)
	{
		_nCurSelectedPath--;
		[_aiLineNumbers retain];
		[self recalculateGraph];
		[self updateInterface];
		return;
	}
	
	_nCurSelectedPath--;
	[_db initialization];
	//int nTime=[_graph getWeight: _nSecondFoundStation];
	int* nAllowed=[_db getUStationsAllowedLinesWithStart:[[_aiLineNumbers objectAtIndex: _nFirstFoundStation] intValue]
												  andEnd:[[_aiLineNumbers objectAtIndex: _nSecondFoundStation] intValue]
												andIndex: _nCurSelectedPath];
	
	int nCount=[_db getUStationsCountOfAllowedLinesArray];
	[_graph applyCyclonC: nAllowed withAllowedCount: nCount];
	[self updateInterface];	
	free(nAllowed);
}

-(void) setSelection:(int)selected
{
	if(_nWhatSt==1){
		_nFirstFoundStation=selected;
		//printf("Found index: %d\n", _nFirstFoundStation);			
	}
	else{
		_nSecondFoundStation=selected;	
		//printf("Found Sec index: %d\n", _nSecondFoundStation);			
	}	
	
	// that stuff shouldn't be here (at any curcumstances):
	self.navigationController.navigationBar.hidden=YES;
	// recalculate the nodes (we've changed nodes structure - while using Modal dialog):
	[self recalculateGraph];
	[self updateInterface];
}

	
#pragma mark -
#pragma mark TabBar dancing
-(void) checkIfNavigationBarIsHidden
{
	// that stuff shouldn't be here (at any curcumstances):
	if(!self.navigationController.navigationBar.hidden){
		[self.navigationController setNavigationBarHidden:YES animated:NO];	
		//[self updateInterface];
	}	
}

- (void)viewWillAppear:(BOOL)animated{
    if(_graph==nil)
	{
		[self loadAllNeededStuff];
	}	
		
	[NSTimer scheduledTimerWithTimeInterval:.1
		 target:self selector:@selector(checkIfNavigationBarIsHidden) userInfo:nil repeats:NO];
	// for the first time th  e upper toolbar is simply shown;
	_bUpperToolbarShown=[master storageGetSelectedStations:5 FromController: @""]==1?true:false;

	_bLoadMyChild=false;    	

	[showSightseeings removeFromSuperview];
	CGRect oldSight=showSightseeings.frame;

	// upper panel button showing...
	btnShowUpperPanel.center = CGPointMake(kScreenWidth - btnShowUpperPanel.frame.size.width/2,
		btnShowUpperPanel.frame.size.height/2);

	// do other needed stuff:
	[upperToolbar removeFromSuperview];

	CGRect old=upperToolbar.frame;
	if(_bUpperToolbarShown){
	    upperToolbar.frame=CGRectMake(old.origin.x, kUndergroundToolbarCyS, old.size.width, old.size.height);
	    upperToolbar.hidden=NO;

	    btnShowUpperPanel.hidden=YES;
	}
	else{
	    upperToolbar.hidden=YES;
		
	    btnShowUpperPanel.hidden=NO;
	}

	[self.tabBarController.view addSubview:upperToolbar];	
	[self.tabBarController.view addSubview:showSightseeings];

	if(_bUpperToolbarShown){
	    [self showToolbarWithAnimationAndInfo:0];	
	}
	else{
	    if(!_bTapWarningWasShown)
		[self showTapWarnWithInfo:0];
	}	
}

- (void)viewWillDisappear:(BOOL)animated{   	
	//[busy startAnimating];	
	//if(_bGoDeeperLevelYourself)
    //[self hideToolbarWithAnimationAndInfo:1];	
	[master storageSetSelectedStations: 3 TheStationValue: _nFirstFoundStation FromController: @""];
    [master storageSetSelectedStations: 4 TheStationValue: _nSecondFoundStation FromController: @""];
	
    [master storageSetSelectedStations: 5 TheStationValue: _bUpperToolbarShown?1:0 FromController: @""];	
	
    [upperToolbar setHidden:YES];	
    [upperToolbar removeFromSuperview];
    [showSightseeings setHidden:YES];
    [showSightseeings removeFromSuperview];
	
    [self.view addSubview:upperToolbar];	
    [self.view addSubview:showSightseeings];
	
    // we load another tab...	
    if(!_bLoadMyChild)
		[self releaseAllStuff];		
}

-(void) showLoadingIndicator
{	
	[busy startAnimating];
}

#pragma mark -
#pragma mark Drawing Process
-(void) drawSelection
{
    if(_bReformDrawBuffer){
	// add the dust to the main image:
	if(_bShowFog)
	if(_nFirstFoundStation!=-1 && _nSecondFoundStation!=-1)
	{
	   [self drawFog]; 
	}
	else
	{
	    [canvas removeFog];
	}
	
	if(_nFirstFoundStation!=-1)
	{
	    UIColor *color=[[UIColor alloc] initWithRed:1.0 green:0.0 blue:0.0 alpha: 0.5];
	    [self drawNodeNormalStation:NO Color:color StationIndex:_nFirstFoundStation];									
	    [color release];		/// if movement was in the play:		
	    //[bottomToolBar setHidden:YES];
	}
	if(_nSecondFoundStation!=-1)
	{		
	    UIColor *color=[[UIColor alloc] initWithRed:1.0 green:0.0 blue:0.0 alpha: 0.5];
	    [self drawNodeNormalStation:NO Color:color StationIndex:_nSecondFoundStation];									
	    [color release];		
	}

	UIColor *colorDest;
	if(!_bShowFog){
		colorDest=[[UIColor alloc] initWithRed:0.5 green:0.5 blue:0.5 alpha: 1.0];
	}
	else{
		colorDest=[[UIColor alloc] initWithRed:0.1 green:0.4 blue:0.9 alpha: 1.0];
		//canvas.backgroundColor = [UIColor colorWithRed:0.7f green:0.81f blue:0.98f alpha:1.0f];
		canvas.backgroundColor = [UIColor colorWithRed:0.0f green:0.4f blue:0.5f alpha:1.0f];
	}
	if(_nSecondFoundStation!=-1 && _nSecondFoundStation!=_nFirstFoundStation && _nFirstFoundStation!=-1){	
	    // first create the path just to see how 
	    // we should draw our arc;
	    //if(_nULineNumbers[_nSecondFoundStation]!=5)
	if([[_aiiULineNumbers objectAtIndex: _nSecondFoundStation] intValue] !=5)
	    [self drawLineWithColor:colorDest StationIndex:_nSecondFoundStation];
	else{
	    [self drawLineWithColor:colorDest StationIndex:_nSecondFoundStation];
	    // for the case we've got only arcs;
	    [self drawArcWithColor:colorDest StationIndex:_nSecondFoundStation];
	}
	    int nLastStation=_nSecondFoundStation;
	    // now draw the other stations (as the route):
	    int parent=[_graph getParent: _nSecondFoundStation];
	    do{	
		// correction to error, which shows up when we select the neighborn station
		if(parent==-1)
		    break;
		//if(parent<0 || parent>N)break;
		// end of correction			
		// draw Info corrections:
		for(int j=0; j<[_aiDrawInfo count]; j++){
		    int nId=[[[_aiDrawInfo objectAtIndex: j] objectForKey: kId] intValue];
		    int nLinkId=[[[_aiDrawInfo objectAtIndex: j] objectForKey: kLinkId] intValue];
		    int nX=[[[_aiDrawInfo objectAtIndex: j] objectForKey: kX] intValue];
		    int nY=[[[_aiDrawInfo objectAtIndex: j] objectForKey: kY] intValue];

		    if((nId==parent && nLinkId==nLastStation) ||
			    (nId==nLastStation && nLinkId==parent))				
			[self drawLineWithColor:colorDest 
				      withPoint: CGPointMake(nX, nY)];
		}

		//if(parent!=kLine1 && parent!=kLine2)
		if([[_aiiULineNumbers objectAtIndex: parent] intValue] !=5)
		  [self drawLineWithColor:colorDest StationIndex:parent];
		else
		  [self drawArcWithColor:colorDest StationIndex:parent];

		nLastStation=parent;
		parent=[_graph getParent: parent];
	    }
	    while(parent!=_nFirstFoundStation);
	    for(int j=0; j<[_aiDrawInfo count]; j++){
		int nId=[[[_aiDrawInfo objectAtIndex: j] objectForKey: kId] intValue];
		int nLinkId=[[[_aiDrawInfo objectAtIndex: j] objectForKey: kLinkId] intValue];
		int nX=[[[_aiDrawInfo objectAtIndex: j] objectForKey: kX] intValue];
		int nY=[[[_aiDrawInfo objectAtIndex: j] objectForKey: kY] intValue];

		if((nId==parent && nLinkId==nLastStation) ||
			(nId==nLastStation && nLinkId==parent))				
		    [self drawLineWithColor:colorDest 
				  withPoint: CGPointMake(nX, nY)];
	    }
	    if(parent!=-1)
		if([[_aiiULineNumbers objectAtIndex: parent] intValue] !=5)
			[self drawLineWithColor:colorDest StationIndex:parent];
		else
			[self drawArcWithColor:colorDest StationIndex:parent];

	}
	
	[colorDest release];
    }
}

// unfortunately I cannot add that stuff
// it doesn't show the contents of down layer...
-(void) drawFog
{
    DrawItem* item=[DrawItem alloc];
    UIColor* color=[[UIColor alloc] initWithRed: 1.0 green: 0.0 blue: 0.0 alpha: 0.5];
    item.color = color;
    item.type = TYPE_FOG;
    UIImage* imageL=[UIImage imageNamed: @"metroImageBlank.png"];
    item.image = imageL;
    item.center = CGPointMake(imageL.size.width/2, imageL.size.height/2);

    [canvas addObjectToDraw:item];
	[color release];
	// can I do it?
	//[imageL release];
}

// draws a station from the centers db
-(void)drawNodeNormalStation:(bool)bOrdinal Color:(UIColor*)color StationIndex:(int)index
{	
	if(_bReformDrawBuffer){
		DrawItem* item=[DrawItem alloc];
		
		if(!bOrdinal)
			item.rad=12;	
		else
			item.rad=6;	
		
		//item.type=TYPE_CIRCLE;	
		//item.type = TYPE_IMAGE;
		item.type = TYPE_ANIMATION;
		item.animationDuration = 2.0f;
				
		item.center=CGPointMake([[_aiCenterX objectAtIndex: index] intValue]+kOffsetXU,
								[[_aiCenterY objectAtIndex: index] intValue]+kOffsetYU);	
		if(index==_nFirstFoundStation)
		    item.animPictures = [NSArray arrayWithObjects: 
					      [UIImage imageNamed:@"endImage.png"], 
					      [UIImage imageNamed:@"endImage1.png"], 
					      [UIImage imageNamed:@"endImage2.png"], 
					      nil];
		    //item.image = [UIImage imageNamed: @"endImage.png"];
		else
		    item.animPictures = [NSArray arrayWithObjects: 
					      [UIImage imageNamed:@"startImage.png"], 
					      [UIImage imageNamed:@"startImage1.png"], 
					      [UIImage imageNamed:@"startImage2.png"], 
					      nil];

		    //item.image = [UIImage imageNamed: @"startImage.png"];

		item.color=color;	
		[canvas addObjectToDraw:item];
	}
}
-(void)drawLineWithColor:(UIColor*)color withPoint:(CGPoint)pt
{
	DrawItem* item=[DrawItem alloc];
	
	item.rad=0;
	item.type=TYPE_LINE;
	item.center=pt;
	item.color=color;
	[canvas addObjectToDraw:item];		
}

-(void)drawLineWithColor:(UIColor*)color StationIndex:(int)index
{	
	DrawItem* item=[DrawItem alloc];
	
	item.rad=0;
	item.type=TYPE_LINE;
	item.center=CGPointMake([[_aiCenterX objectAtIndex: index] intValue]+kOffsetXU,
							[[_aiCenterY objectAtIndex: index] intValue]+kOffsetYU);
	item.color=color;
	[canvas addObjectToDraw:item];		
}

-(void)drawArcWithColor:(UIColor*)color StationIndex:(int)index
{
	DrawItem* item=[DrawItem alloc];
	
	item.rad=0;
	item.type=TYPE_ARC;
	item.center=CGPointMake([[_aiCenterX objectAtIndex: index] intValue]+kOffsetXU,
							[[_aiCenterY objectAtIndex: index] intValue]+kOffsetYU);

	item.nodeNum = index;
	item.color=color;
	[canvas addObjectToDraw:item];
}


#pragma mark -
#pragma mark Delegates

-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
	_bLoadMyChild=true;
	//printf("Ha-ha!\n");
	if(selectStations==nil)
	{
		uStationSelector* stats=[[uStationSelector alloc] initWithNibName:@"uStationSelector" bundle:nil];		
		self.selectStations=stats;
		[stats release];
	}
	// set the flag to see, what station we did selected:
	_nWhatSt=textField.tag;
       [self.selectStations setStationsInfo: _aiULineNames
		 withCount: [_aiUStationNames count]
		 andController: self
		 andDb: _db];

	//[selectStations readAll];	
	// set the flag, that we shouldn't add and delete toolbar from the main window:
	//_bGoDeeperLevelYourself=true;	
	[self.navigationController pushViewController:self.selectStations animated:YES];
	/*
	[NSTimer scheduledTimerWithTimeInterval:1.0
									 target:self selector:@selector(testTextLighting) userInfo:nil repeats:YES];	
	 */
	return FALSE;	
}
//bool gbTest=false;
-(void) testTextLighting
{
    /*
	if(gbTest)
	{
		if(_nWhatSt==1)
			station1.borderStyle=UITextBorderStyleLine;
			//station1.textColor=[UIColor colorWithRed:1.0f green:0.0f blue:0.0f alpha:1.0];
		else
			station2.borderStyle=UITextBorderStyleLine;
			//station2.textColor=[UIColor colorWithRed:1.0f green:0.0f blue:0.0f alpha:1.0];
	}
	else
	{
		if(_nWhatSt==1)
			station1.borderStyle=UITextBorderStyleRoundedRect;
			//station1.textColor=[UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:1.0];
		else
			station2.borderStyle=UITextBorderStyleRoundedRect;
			//station2.textColor=[UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:1.0];		
	}
	gbTest=!gbTest;
	*/
}

-(IBAction) showHelp
{
	if (self.helpController == nil)
        self.helpController = [[[helpForUnderground alloc] initWithNibName:@"helpForUnderground" bundle:nil] autorelease];
	
	_bLoadMyChild=true;
	[self.navigationController presentModalViewController:self.helpController animated:YES];		
}

-(IBAction) resetStation:(id) button
{
	if(((UIButton*)button).tag==1)
		_nFirstFoundStation=-1;
	else
		_nSecondFoundStation=-1;	
	//[self recalculateGraph];
	[self updateInterface];	
}

-(IBAction) changeBigSmallUpBar
{
    _bBigToolbarWasShownBefore=true;
	_bBigUpBar=!_bBigUpBar;
	
	// TODO: add normal show small|big button here!	
	if(!_bBigUpBar){
		upperShowButton.hidden=YES;		
		minusSymbol.hidden=NO;
	}
	else{
		minusSymbol.hidden=YES;
		upperShowButton.hidden=NO;
	}
		
	[self showToolbarWithAnimationAndInfo:1];
}

-(IBAction) showInfoWindow
{
	if(infoWindow!=nil)
	{
		[infoWindow release];
		infoWindow = nil;
	}
	//showInfoWindow* info=
	infoWindow=[[showInfoWindow alloc] initWithNibName:@"showInfoWindow" bundle:nil];	
	//[info release];
	
	
	_bLoadMyChild=true;
	[self.infoWindow setStationInfo:_nFirstFoundStation andSecond:_nSecondFoundStation];
	[self.navigationController pushViewController:self.infoWindow animated:YES];
}

-(IBAction) showHideUpperPanelOnButton
{
	[self showToolbarWithAnimationAndInfo:0];	
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
#pragma mark -
#pragma mark Animation
#pragma mark Tap warning

-(void) hideTapWarnWithInfo:(int)nInfo
{
	////self.scrollView.userInteractionEnabled = NO;
	
	if(!self.navigationController.navigationBar.hidden){
		[self.navigationController setNavigationBarHidden:YES animated:NO];	
		[self updateInterface];
	}
	
	//_dyAnimation=1.0f;
	
	if(_bAreWeInScrollMode)
	{
		[tapWarning setHidden:YES];
		////self.scrollView.userInteractionEnabled = YES;		
	}
	else
		[tapWarning setHidden:YES];
	/*
	else
		if(nInfo==0)
			[NSTimer scheduledTimerWithTimeInterval:kTimeAnimation 
											 target:self selector:@selector(fadeOutToolbar:) userInfo:nil repeats:YES];
		else if(nInfo==1)
			[NSTimer scheduledTimerWithTimeInterval:kTimeAnimation 
											 target:self selector:@selector(fadeOutToolbarSimple:) userInfo:nil repeats:YES];
	 */
}

-(void) showTapWarnWithInfo:(int)nInfo
{
	//self.scrollView.userInteractionEnabled = NO;	
	//_dyAnimation=0.5f;	
	//CGRect old=tapWarning.frame;
	// show our baby:
	
	if(nInfo==0)
		tapWarning.frame=CGRectMake(10, kTapWarningCy, 
									  300, 29);
		
	tapWarning.hidden=NO;	
	
	tapWarning.frame=CGRectMake(10, kTapWarningCy, 
								300, 29);	
	 
	_bTapWarningWasShown=true;
	
	//printf("Warning was shown!\n");	
	[NSTimer scheduledTimerWithTimeInterval:2.5f target:self 
								   selector:@selector(hideTapWarnTmr) userInfo:nil repeats:NO];	
	 
}

-(void) hideTapWarnTmr
{	
	//printf("Warning was hidden!\n");
	[self hideTapWarnWithInfo:0];
}

#pragma mark upperToolbar
-(void) hideToolbarWithAnimationAndInfo:(int)nInfo
{
	////self.scrollView.userInteractionEnabled = NO;
	
	if(!self.navigationController.navigationBar.hidden){
		[self.navigationController setNavigationBarHidden:YES animated:NO];	
		[self updateInterface];
	}
	
	if(!_bTapWarningWasShown)
	{
		//printf("Show tap warning!\n");
		[self showTapWarnWithInfo:0];
	}
	
	_dyAnimation=1.0f;	
	if(_bAreWeInScrollMode)
	{
		[upperToolbar setHidden:YES];
		btnShowUpperPanel.hidden=NO;
		////self.scrollView.userInteractionEnabled = YES;		
	}
	else
	if(nInfo==0)
		[NSTimer scheduledTimerWithTimeInterval:kTimeAnimation 
										 target:self selector:@selector(fadeOutToolbar:) userInfo:nil repeats:YES];
	else if(nInfo==1)
		[NSTimer scheduledTimerWithTimeInterval:kTimeAnimation 
										 target:self selector:@selector(fadeOutToolbarSimple:) userInfo:nil repeats:YES];
}

-(void) showToolbarWithAnimationAndInfo:(int)nInfo
{
	//self.scrollView.userInteractionEnabled = NO;
	
	_dyAnimation=0.5f;	
	CGRect old=upperToolbar.frame;
	// show our baby:
	if(nInfo==0)
	upperToolbar.frame=CGRectMake(old.origin.x, kUndergroundToolbarCyS, 
								   old.size.width, old.size.height);
	upperToolbar.hidden=NO;
	btnShowUpperPanel.hidden=YES;
	
	if(_bAreWeInScrollMode)
	{	
		int kCy;
		if(_bBigUpBar)
			kCy=kUndergroundToolbarCyBig;
		else
			kCy=kUndergroundToolbarCy;			

		upperToolbar.frame=CGRectMake(old.origin.x, kCy, 
									  old.size.width, old.size.height);
		_bUpperToolbarShown=true;
		//self.scrollView.userInteractionEnabled = YES;
	}
	else
	if(nInfo==0){
		[NSTimer scheduledTimerWithTimeInterval:kTimeAnimation target:self 
									   selector:@selector(fadeInToolbar:) userInfo:nil repeats:YES];	
	}
	else if(nInfo==1 && _bBigUpBar)
	{
		[NSTimer scheduledTimerWithTimeInterval:kTimeAnimation target:self 
									   selector:@selector(fadeInToolbar:) userInfo:nil repeats:YES];
	}
	else if(nInfo==1 && !_bBigUpBar)
	{		
		[NSTimer scheduledTimerWithTimeInterval:kTimeAnimation target:self 
									   selector:@selector(fadeOutToolbarForHideTimeInfo:) userInfo:nil repeats:YES];
		
	}
}

- (void)fadeOutToolbarSimple:(NSTimer*)theTimer
{
	CGRect old=upperToolbar.frame;
	_dyAnimation*=1.25;
	upperToolbar.frame=CGRectMake(old.origin.x, old.origin.y-_dyAnimation, 
								   old.size.width, old.size.height);
	if(old.origin.y<kUndergroundToolbarCyS+10){
		[theTimer invalidate];
		[upperToolbar setHidden:YES];
		btnShowUpperPanel.hidden=NO;
		//self.scrollView.userInteractionEnabled = YES;
	}
	
} 

- (void)fadeOutToolbar:(NSTimer*)theTimer
{
	CGRect old=upperToolbar.frame;
	_dyAnimation*=1.25;
	upperToolbar.frame=CGRectMake(old.origin.x, old.origin.y-_dyAnimation, 
								   old.size.width, old.size.height);
	if(old.origin.y<kUndergroundToolbarCyS + 10){
		[theTimer invalidate];		
		btnShowUpperPanel.hidden=NO;
		//self.scrollView.userInteractionEnabled = YES;
	}
}

-(void)fadeOutToolbarForHideTimeInfo:(NSTimer*)theTimer
{
	CGRect old=upperToolbar.frame;
	_dyAnimation*=1.25;
	upperToolbar.frame=CGRectMake(old.origin.x, old.origin.y-_dyAnimation, 
								  old.size.width, old.size.height);
	if(old.origin.y<kUndergroundToolbarCy+5){
		[theTimer invalidate];
		//[upperToolbar setHidden:NO];
		upperToolbar.frame=CGRectMake(old.origin.x, kUndergroundToolbarCy, 
									  old.size.width, old.size.height);
		//self.scrollView.userInteractionEnabled = YES;
	}	
}

- (void)fadeInToolbar:(NSTimer*)theTimer
{
	
	CGRect old=upperToolbar.frame;
	_dyAnimation*=1.25;
	upperToolbar.frame=CGRectMake(old.origin.x, old.origin.y+_dyAnimation, 
								   old.size.width, old.size.height);
	//printf("Fade in toolbar! %.0f\n", old.origin.y-_dyAnimation);
	int kCy;
	if(_bBigUpBar)
		kCy=kUndergroundToolbarCyBig;
	else
		kCy=kUndergroundToolbarCy;
		
	if(old.origin.y>kCy-10){
		[theTimer invalidate];
		upperToolbar.frame=CGRectMake(old.origin.x, kCy, 
									   old.size.width, old.size.height);
		//self.scrollView.userInteractionEnabled = YES;
		_bUpperToolbarShown=true;
	}	
}
#pragma mark InfoToolbar
- (void)fadeOutToolbarInfo:(NSTimer*)theTimer
{
	CGRect old=showSightseeings.frame;
	_dyAnimation*=1.25;
	showSightseeings.frame=CGRectMake(old.origin.x+_dyAnimation, old.origin.y, 
									  old.size.width, old.size.height);
	//printf("Fade in toolbar! %.0f\n", old.origin.y-_dyAnimation);	
	
	if(old.origin.x>kScreenWidth-10){
		[theTimer invalidate];
		showSightseeings.frame=CGRectMake(kScreenWidth, old.origin.y, 
										  old.size.width, old.size.height);
		showSightseeings.hidden=YES;
		
		//self.scrollView.userInteractionEnabled = YES;
	}	
	
	
}
- (void)fadeInToolbarInfo:(NSTimer*)theTimer
{
	CGRect old=showSightseeings.frame;
	_dyAnimation*=1.25;
	showSightseeings.frame=CGRectMake(old.origin.x-_dyAnimation, old.origin.y, 
								  old.size.width, old.size.height);
	//printf("Fade in toolbar! %.0f\n", old.origin.y-_dyAnimation);	
	
	if(old.origin.x<kScreenWidth-old.size.width-10){
		[theTimer invalidate];
		showSightseeings.frame=CGRectMake(kScreenWidth-old.size.width, old.origin.y, 
									  old.size.width, old.size.height);
		//self.scrollView.userInteractionEnabled = YES;
	}	
	
		
}

-(void) hideToolbarInfoWithAnimationAndInfo:(int)nInfo
{
	//self.scrollView.userInteractionEnabled = NO;
	_dyAnimation=0.5f;
	
	if(_bAreWeInScrollMode)
	{
		showSightseeings.hidden=YES;				
		//self.scrollView.userInteractionEnabled = YES;		
	}	
	else
	if(nInfo==0){
		[NSTimer scheduledTimerWithTimeInterval:kTimeAnimation target:self 
									   selector:@selector(fadeOutToolbarInfo:) userInfo:nil repeats:YES];	

	}		
}

-(void) showToolbarInfoWithAnimationAndInfo:(int)nInfo
{	
	//self.scrollView.userInteractionEnabled = NO;
	_dyAnimation=0.5f;	
	CGRect oldSight=showSightseeings.frame;
	// show our baby:
	showSightseeings.hidden=NO;
	showSightseeings.frame=CGRectMake(kScreenWidth, 
									  kScreenHeight-kTabBarHeight-oldSight.size.height,
								  oldSight.size.width, oldSight.size.height);
	
	if(_bAreWeInScrollMode)
	{
		showSightseeings.frame=CGRectMake(kScreenWidth-oldSight.size.width, 
										  kScreenHeight-kTabBarHeight-oldSight.size.height,
										  oldSight.size.width, oldSight.size.height);
	}
	else	
	if(nInfo==0){
		[NSTimer scheduledTimerWithTimeInterval:kTimeAnimation target:self 
									   selector:@selector(fadeInToolbarInfo:) userInfo:nil repeats:YES];	
	}
}


#pragma mark -
#pragma mark Deallocation of resources

- (void)didReceiveMemoryWarning {
	// Releases the view if it doesn't have a superview.
    //[self releaseAllStuff];
    [super didReceiveMemoryWarning];
	// Release any cached data, images, etc that aren't in use.	
}

- (void)viewDidUnload {
	// Release any retained subviews of the main view.
	// e.g. self.myOutlet = nil;
	//printf("Underground: viewDidUnload!\n");
	// release elements:
	/// ERROR was here! EXC_BAD_ACCESS!
	/*
	if(image!=nil)
		[image release];	
	if(scrollView!=nil)
		[scrollView release];
	if(upperToolbar!=nil)
		[upperToolbar release];
	if(selectStations!=nil)
		[selectStations release];
	*/
	if(_db!=nil)
	{
		
	}
		
	// set them to nil:	
	self.image=nil;	
	self.scrollView=nil;	
	self.databaseName=nil;
	self.upperToolbar=nil;
	self.selectStations=nil;
}

- (void)dealloc {
	//printf("Underground: dealloc!\n");
	/*
	if(scrollView!=nil)
		[scrollView release];
	if(databaseName!=nil)	   
		[databaseName release];
	if(image!=nil)
		[image release];
	*/
    [super dealloc];
}

@end
